<?php

namespace Hilaoyu\LaravelExtend\Services\Auth\Redefinition;

use Carbon\Carbon;
use Hilaoyu\LaravelExtend\Services\Auth\AuthService;
use Hilaoyu\Utils\UtilSupport;
use Illuminate\Auth\SessionGuard;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Illuminate\Auth\EloquentUserProvider;


class EloquentUserWithMultipleAuthTokenProvider extends EloquentUserProvider
{

    public function __construct(HasherContract $hasher, $model)
    {
        parent::__construct($hasher, $model);

        $this->createModel()->clearExpireToken();
    }


    public function retrieveById($identifier)
    {

        $user =  parent::retrieveById($identifier);
        $token = null;
        $guard = AuthService::Guard();

        if($user && $guard instanceof SessionGuard){
            $token_id = session($guard->getName().'_token_id');
            if(!$token_id){
                return null;
            }
//            $token = $user->auth_token()->where('id','=',$token_id)->where('expire_time','>',Carbon::now())->first();
            // 从缓存中读取Token
            $token = Cache::get(AuthService::GetTokenCahceKeyPrefix().$token_id);
            //dump($user->auth_token()->where('id','=',$token_id)->toRawSql());
            //abort(200);
            if(!$token){
                return null;
            }
            $user->setAuthenticatedToken($token);
        }



        return AuthService::LoginRefresh($user,$token);
    }

    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials)
    {
        $token_id = '';

        if (empty($credentials) ||
            (count($credentials) === 1 &&
                array_key_exists('password', $credentials))) {
            return;
        }

        // First we will add each credential element to the query as a where clause.
        // Then we can execute the query and, if we found a user, return it in a
        // Eloquent User "model" that will be utilized by the Guard instances.
        $user_model = $this->createModel();
        $query = $user_model->newQuery();
        $token = $user = null;
        $has_other_credentials = false;
        foreach ($credentials as $key => $value) {
            if (Str::contains($key, 'password')) {
                continue;
            }
            if ( Str::contains($key, 'api_token')) {
                $token_id = Arr::get($credentials,$key);
                /*$query = $query->whereHas('auth_token',function ($tq) use ($token_id){
                    return $tq->where('id','=',$token_id)->where('expire_time','>',Carbon::now());
                });*/
                $token = Cache::get(AuthService::GetTokenCahceKeyPrefix().$token_id);
                continue;
            }
            $query->where($key,'=', $value);
            $has_other_credentials = true;
        }

//        $token = null;
        if ($token){
            $user = $query->where('id',data_get($token,'user_id'))->first();
        }elseif ($has_other_credentials){
            $user = $query->first();
        }
        if (!$user){
            return  null;
        }
        if($user && $token_id){
            /*$token = $user->auth_token()->where('id','=',$token_id)->first();
            if($token){
                $user->setAuthenticatedToken($token);
            }*/
            $user->setAuthenticatedToken($token);
        }


        return  AuthService::LoginRefresh($user,$token);
    }

}
